package com.example.experimen2;

import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.GridLayout;
import android.widget.ToggleButton;

import com.example.experimen2.algorithm.FruitLink;
import com.example.experimen2.algorithm.FruitInitializer;
import com.example.experimen2.constraint.Constraint;
import com.example.experimen2.data.Fruit;

public class GameAreaView extends GridLayout {

    private static final String TAG = "GameView";
    private Fruit[][] fruits;

    private int rowCount;//行数
    private int columnCount;//列数

    private int checkedFruitCount; //标记：当前选中的图片数量
    private ToggleButton lastCheckedButton;//标记：上一个被选中的水果
    private MainActivity context;//上下文，动态创建水果的ToggleButton要用到

    private Animation fadeOut;
    private GameSound gameSound;

    /**
     * 要重写这个父类GridLayout构造器，才能在XML中使用，否则会报错
     *
     * @param context
     * @param attrs
     */
    public GameAreaView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void startGame(MainActivity context) {
        this.context = context;
        rowCount = getRowCount();
        columnCount = getColumnCount();

        fadeOut = AnimationUtils.loadAnimation(context, R.anim.scale_fade_out);


        //将水果图片添加到游戏区域
        refreshGameBoard();
    }

    public void refreshGameBoard() {
        loadSoundAndPlayBGM();
        //界面上没有水果，初始化界面
        fruits = new FruitInitializer().initialGameInterface(rowCount, columnCount);
        for (int i = 0; i < fruits.length; i++) {
            for (int j = 0; j < fruits[i].length; j++) {
                Fruit fruit = fruits[i][j];
                ToggleButton toggleButton = new ToggleButton(context);
                toggleButton.setBackgroundResource(fruit.getImageId());
                toggleButton.setText("");
                toggleButton.setTextOn("");
                toggleButton.setTextOff("");
                toggleButton.setTag(fruit);

                //为每个水果图片控件添加单击监听事件，以下是连连看消除判断逻辑：
                //1. 使用checkedFruitCount计数当前游戏区内被选中的水果数量
                //2. 当某个图片被选中时：checkedFruitCount + 1
                //      2.1 当游戏区域内被选中的水果数量为1时：记录下被选中的水果 -> lastCheckedButton = checkedButton
                //      2.2 当游戏区域内被选中的水果数量为2时：比较{此次被选中的水果} vs {上次选中的水果}，判断它们是否可以连接
                //                                   2.2.1 如果可以连接：从布局中移除它们，游戏加分
                //                                   2.2.2 如果不可以连接：取消选中它们，checkedFruitCount = 0，游戏继续
                //3. 当某个图片被取消选中时：checkedFruitCount - 1
                toggleButton.setOnClickListener(v -> {
                    ToggleButton checkedButton = (ToggleButton) v;
                    if (checkedButton.isChecked()) {
                        checkedFruitCount++;
                        if (checkedFruitCount == 1) {
                            lastCheckedButton = checkedButton;
                        } else if (checkedFruitCount == 2 && lastCheckedButton != null) {
                            if (canConnect(checkedButton, lastCheckedButton)) {
                                //能够相连，则消除这两个水果
                                connect(checkedButton, lastCheckedButton);
                            } else {
                                lastCheckedButton.setChecked(false);
                                checkedButton.setChecked(false);

                                gameSound.playSound(Constraint.CONNECT_FAILED);
                            }

                            checkedFruitCount = 0;
                            lastCheckedButton = null;
                        }
                    } else {
                        checkedFruitCount--;
                    }
                });

                addView(toggleButton, 170, 170);
            }
        }
    }

    private void loadSoundAndPlayBGM() {
        gameSound = GameSound.getInstance(context);
        gameSound.loadSound();
        gameSound.playGameBGM();
    }


    /**
     * 判断两个水果图片是否可以消除
     *
     * @param checkedFruit
     * @param lastCheckedFruit
     * @return
     */
    public boolean canConnect(ToggleButton checkedFruit, ToggleButton lastCheckedFruit) {
        //先判断两个水果图片是否相同
        Fruit fruit1 = (Fruit) checkedFruit.getTag();
        Fruit fruit2 = (Fruit) lastCheckedFruit.getTag();
        if (fruit1.getImageId() == fruit2.getImageId()) {
            return true;
            //广度优先搜索
//            return new FruitLink().evaluateFruitConnections(fruit1, fruit2, fruits);
        } else {
            return false;
        }


    }

    /**
     * 消除两个水果响应的逻辑
     *
     * @param checkedButton
     * @param lastCheckedButton
     */
    private void connect(ToggleButton checkedButton, ToggleButton lastCheckedButton) {
        //播放消失动画
        lastCheckedButton.startAnimation(fadeOut);
        checkedButton.startAnimation(fadeOut);

        //播放消除音效
        gameSound.playSound(Constraint.CONNECT_SUCCESS);

        //移除元素
        removeViewInLayout(checkedButton);
        removeViewInLayout(lastCheckedButton);
        fruits[((Fruit) checkedButton.getTag()).getRow()][((Fruit) checkedButton.getTag()).getColumn()] = null;
        fruits[((Fruit) lastCheckedButton.getTag()).getRow()][((Fruit) lastCheckedButton.getTag()).getColumn()] = null;

        //更新分数
        context.updateScore(2);
        //每一次消除成功后，需要判断游戏是否已经结束
        if (isGameOver()) {
            gameOver();
        }

    }

    public void stopGame() {
        gameSound.stopGameBGM();
        gameSound.release();
    }

    public void gameOver() {
        //判断游戏通关还是失败
        int childCount = getChildCount();
        if (childCount == 0) {
            gameSound.playSound(Constraint.WIN);
            context.gameWin();
        } else {
            gameSound.playSound(Constraint.LOSE);
            context.gameLose();
        }
        gameSound.stopGameBGM();
    }

    private boolean isGameOver() {
        int childCount = super.getChildCount();
        if (childCount == 0) {
            return true;
        }
        return false;
    }
}
